/* -*- mode: c++; coding: utf-8-unix -*-
 */

#ifndef _ALGORITHM_H
#define _ALGORITHM_H

#include "Image.h"
#include <assert.h>
#include <string>

namespace alg
{
	using namespace img;

	class ChDef
	{
		Image *_image;
		Channel _channel;
	public:
		ChDef() : _image(0), _channel(None) {}
		ChDef(Image *img, Channel ch)
			: _image(img), _channel(ch) {}
		inline Image *image() const { return _image; }
		inline Channel channel() const { return _channel; }

		std::string toString() const;
	};

	class Workunit
	{
		ChDef _source;
		img::size_type _startLine, _numLines;
		bool _center;
	protected:
		Workunit(bool center, ChDef src)
			: _center(center), _source(src) {}
	public:
		static Workunit* create(bool dft, bool center, const ChDef &src);
		virtual ~Workunit() {}
		
		inline const ChDef &source() const { return _source; }

		virtual std::string toString() const;
		inline img::size_type startLine() const { return _startLine; }
		inline img::size_type numLines() const { return _numLines; }
		inline void startLine(img::size_type n) { _startLine=n; }
		inline void numLines(img::size_type n) { _numLines=n; }
		inline void range(img::size_type start, img::size_type num)
		{
			startLine(start);
			numLines(num);
		}
		inline bool center() const { return _center; }
	};
	class DCT_Workunit : public Workunit
	{
		ChDef _dest;

		friend class Workunit;
		DCT_Workunit(bool center, const ChDef &src)
			: Workunit(center, src) {}
		
	public:
		inline const ChDef &dest() const { return _dest; }
		inline void dest(const ChDef &cd) { _dest = cd; }

		std::string toString() const;
	};

	class DFT_Workunit : public Workunit
	{
		ChDef _realDest, _imagDest, _magnitudeDest, _phaseDest;

		friend class Workunit;
		DFT_Workunit(bool center, const ChDef &src)
			: Workunit(center, src) {}
	public:
		inline const ChDef &realDest() const { return _realDest; }
		inline const ChDef &imagDest() const { return _imagDest; }
		inline const ChDef &magnitudeDest() const { return _magnitudeDest; }
		inline const ChDef &phaseDest() const { return _phaseDest; }

		inline void realDest(const ChDef &cd) { _realDest = cd; }
		inline void imagDest(const ChDef &cd) { _imagDest = cd; }
		inline void magnitudeDest(const ChDef &cd) { _magnitudeDest = cd; }
		inline void phaseDest(const ChDef &cd) { _phaseDest = cd; }

		std::string toString() const;
	};

	void dft(const DFT_Workunit &wu);
	void dct(const DCT_Workunit &wu);
}

#endif //_ALGORITHM_H
